Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

48장. ECS Service Discovery — Cloud Map

이 장에서 말하고자 하는 것

ALB는 외부 트래픽을 분배해준다.

그런데 컨테이너끼리 서로 부를 때는 어떻게 할까?

orders 컨테이너 → users 컨테이너 호출

이때 매번 새 Task의 IP를 알아내기는 어렵다.

이 문제를 푸는 게

AWS Cloud Map

이고 ECS에서 이걸 활용하는 기능이

ECS Service Discovery

다.


1. 무엇을 해결하는가

ECS Task는 IP가 자주 바뀐다.

users-task-1 : 10.0.1.10
users-task-2 : 10.0.2.11
... 죽고 살고 ...
users-task-3 : 10.0.1.45

대신 Service에 이름을 붙이면

users.local

이 이름이 자동으로 현재 살아 있는 Task의 IP들을 가리킨다.

다른 컨테이너는 http://users.local:8080 으로 부르기만 하면 된다


2. 동작 구조

[ECS Service "users"]
  ├─ task 1 (10.0.1.10)
  └─ task 2 (10.0.2.11)
       ↓ 자동 등록
[Cloud Map: users.local]
  ├─ A 10.0.1.10
  └─ A 10.0.2.11
       ↓ DNS 질의
[orders 컨테이너] → users.local 으로 요청

Task가 뜨고 죽을 때마다 Cloud Map의 DNS가 자동으로 갱신된다


3. ALB와 Service Discovery는 자리가 다르다

ALB              → 외부 사용자 → 서비스
Service Discovery → 서비스 ↔ 서비스 (내부)
  • ALB: L7 라우팅, 인증서, 헬스 체크 정밀
  • Service Discovery: 단순 DNS, 내부 식별

내부 호출에 ALB를 또 두면

  • 비용이 든다
  • 지연이 늘어난다
  • 트래픽이 굳이 외부 경로를 흉내 낸다

내부 호출은 Service Discovery로.


4. Service Connect — 더 단단한 옵션

ECS는 Service Connect 라는 진화된 방식도 제공한다.

  • DNS 기반 + 사이드카 프록시
  • 자동 재시도 · 타임아웃 · 메트릭
  • HTTP/2 · gRPC 지원

새로 시작하는 프로젝트라면 Service Connect 부터 검토해도 좋다.


5. 우리 서비스에서

[ALB]   ← 외부 트래픽
   ↓
[ECS Service: web]
   ↓ http://users.local
[ECS Service: users]
   ↓ http://payments.local
[ECS Service: payments]
  • 외부 → 내부: ALB
  • 내부 → 내부: Service Discovery (또는 Service Connect)

6. 직접 확인해보기 — CLI

aws servicediscovery create-private-dns-namespace \
  --name local \
  --vpc <vpc-id>

aws servicediscovery create-service \
  --name users \
  --dns-config "NamespaceId=<ns-id>,DnsRecords=[{Type=A,TTL=10}]"

dig users.local

VPC 안에서만 응답한다.


7. 코드로는 이렇게 생겼다 — Terraform

resource "aws_service_discovery_private_dns_namespace" "main" {
  name = "local"
  vpc  = aws_vpc.main.id
}

resource "aws_service_discovery_service" "users" {
  name = "users"

  dns_config {
    namespace_id = aws_service_discovery_private_dns_namespace.main.id

    dns_records {
      type = "A"
      ttl  = 10
    }
  }
}

resource "aws_ecs_service" "users" {
  name            = "users"
  cluster         = aws_ecs_cluster.main.id
  task_definition = aws_ecs_task_definition.users.arn
  desired_count   = 2
  launch_type     = "FARGATE"

  network_configuration {
    subnets         = [aws_subnet.private_a.id, aws_subnet.private_b.id]
    security_groups = [aws_security_group.task.id]
  }

  service_registries {
    registry_arn = aws_service_discovery_service.users.arn
  }
}

service_registries 한 줄이
ECS Service와 Cloud Map을 묶는다.


8. 이렇게 쓰면 망한다 — 안티패턴

안티패턴 1. 내부 호출에도 ALB를 둔다

비용 · 지연 · 복잡도 모두 늘어난다.

안티패턴 2. DNS TTL을 길게 둔다

Task가 죽었는데 클라이언트가 옛 IP로 계속 보낸다.

내부 Discovery DNS의 TTL은 짧게 (10초 권장)

안티패턴 3. 애플리케이션에서 DNS를 한 번만 해석한다

일부 언어/라이브러리는 부팅 시 DNS만 보고 캐싱한다.
이러면 TTL이 짧아도 의미가 없다.

매 호출마다 새로 해석하거나, 짧은 캐시를 명시적으로 켠다

안티패턴 4. Service Discovery를 외부 트래픽에 쓴다

.local 은 VPC 내부에서만 응답한다.


9. 한 줄로 정리

Service Discovery는 자주 바뀌는 컨테이너 IP를
이름 하나로 안정적으로 부를 수 있게 만든다


10. 이 장의 핵심 정리

  1. ECS Task는 IP가 자주 바뀌므로 내부 호출에 이름이 필요하다.
  2. Cloud Map은 Task를 자동으로 DNS에 등록해준다.
  3. ALB는 외부 트래픽, Service Discovery는 내부 호출이다.
  4. DNS TTL은 짧게, 클라이언트 캐시도 점검한다.
  5. 새 프로젝트는 Service Connect 도 검토할 가치가 있다.